package com.lee.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lihaiqiang
 * @date 2021/5/19
 */
public class SvnStatisticsUtil {
    public static final String START_TIME = "2021-05-01 00:00:00";
    public static final String END_TIME = "2021-05-31 23:59:59";
    public static final String PROJECT_PATH = "D:\\Aspire\\project\\JSHDC_PROJECT\\trunk\\code\\Android_Client\\ASP_CLOUD_Game";
    public static final String PROJECT_URL = "https://10.1.3.80:8443/svn/JSHDC_PROJECT/trunk/code";

    public static void main(String[] args) throws Exception {
        svnStatistics(args);
    }

    private static void svnStatistics(String[] args) throws Exception {
        Map<String, String> paramMap = parseParams(args);

        String startTime = paramMap.get("startTime") != null ? paramMap.get("startTime") : START_TIME;
        String endTime = paramMap.get("endTime") != null ? paramMap.get("endTime") : END_TIME;
        String target = paramMap.get("target") != null ? paramMap.get("target") : PROJECT_URL;
        System.out.println("startTime: " + startTime);
        System.out.println("endTime: " + endTime);
        System.out.println("target: " + target);

        String cmd = String.format("svn log -r {\"%s\"}:{\"%s\"} %s", startTime, endTime, target);
        Map<String, List<String>> verMap = new HashMap<>(32);
        exec(cmd, line -> {
            //System.out.println(line);
            if (line.startsWith("r") && line.endsWith("line")) {
                String[] s = line.split("\\|");
                List<String> verList = verMap.computeIfAbsent(s[1].trim(), s1 -> new ArrayList<>());
                verList.add(s[0].trim().substring(1));
                //System.out.println(s[0].trim().substring(1) + "\n");
            }
        });

        int total = 0;
        for (String key : verMap.keySet()) {
            List<String> versionList = verMap.get(key);
            // [全部,代码,注释,空行]
            final int[] count = new int[]{0, 0, 0, 0};
            for (String ver : versionList) {
                cmd = String.format("svn diff -c %s %s", ver, target);
                exec(cmd, line -> {
                    if (line.startsWith("+") && !line.startsWith("++")) {
                        count[0]++;
                        String str = line.substring(1).trim();
                        if (isBlank(str)) {
                            // 空行
                            count[3]++;
                        } else if (str.startsWith("/") || str.startsWith("*")) {
                            // 注释
                            count[2]++;
                        } else {
                            // 代码
                            count[1]++;
                        }
                    }
                });
            }
            System.out.println(key + ": a=" + count[0] + ", c=" + count[1] + ", d=" + count[2] + ", s=" + count[3]);
            total += count[0];
        }
        System.out.println("Total: " + total);
    }

    private static void exec(String cmd, OnReadLineListener listener) throws Exception {
        InputStream is = Runtime.getRuntime().exec(cmd).getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "GBK"));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            listener.onRead(line);
        }
    }

    private static Map<String, String> parseParams(String[] params) {
        Map<String, String> paramMap = new HashMap<>(16);
        for (String param : params) {
            System.out.println("param: " + param);
            String[] p = param.split("=");
            paramMap.put(p[0].trim(), p[1].trim());
        }
        return paramMap;
    }

    public static boolean isBlank(final CharSequence cs) {
        final int strLen = length(cs);
        if (strLen == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static int length(final CharSequence cs) {
        return cs == null ? 0 : cs.length();
    }

    interface OnReadLineListener {
        void onRead(String line);
    }
}
